<?php

namespace app\models;

use yii;
use yii\data\Pagination;
use yii\db\Command;
use yii\db\Exception;

/**
 * 模型基类
 */
class ActiveRecord extends \yii\db\ActiveRecord
{
    protected static $page = 0;
    protected static $count = 0;
    protected static $pageSize = 0;

    /**
     * 获取当前模型的主键值
     * @return string
     */
    public static function getPk()
    {
        $pkArr = static::primaryKey();
        return $pkArr[0];
    }

    /**
     * AR单表记录添加
     * @param $attr
     * @return bool
     */
    public static function newCreate($attr)
    {
        $model = new static();
        $model->setAttributes($attr);
        return $model->save(false);
    }

    /**
     * AR根据主键单条数据更新
     * @param $attr
     * @param $pkValue
     * @return int
     */
    public static function updateByPk($attr, $pkValue)
    {
        $pk = static::getPk();
        return static::updateAll($attr, [$pk => $pkValue]);
    }

    /**
     * Notes:AR真实删除数据
     * Date: 2020/7/24
     * Time: 11:16
     * @param $id
     * @return int
     */
    public static function realDeleteById($id)
    {
        return static::deleteAll([static::getPk() => $id]);
    }

    /**
     * 根据主键查询单条（ 单表查询 ）数据
     * 以数组返回
     * @param $pkValue
     * @param string[] $select
     * @return array|yii\db\ActiveRecord|null
     */
    public static function getSingleByPk($pkValue, $select = ['*'])
    {
        $pk = static::getPk();
        $query = static::find();
        $query->select($select);
        $query->where([$pk => $pkValue]);
        $query->asArray();
        return $query->one();
    }

    /**
     * Notes:获取列表
     * Date: 2020/6/17
     * Time: 11:29
     * @param array $params
     * @return array|bool|int|string|\yii\db\ActiveRecord|\yii\db\ActiveRecord[]|null
     */
    public static function getList($params = [])
    {
        $query = static::find();
        if (isset($params['select'])) {
            $query->select($params['select']);
        } else {
            $query->select(static::getPk());
        }
        if (isset($params['where'])) {
            $query->where($params['where']);
        }
        if (isset($params['orderBy'])) {
            $query->orderBy($params['orderBy']);
        }
        if (isset($params['groupBy'])) {
            $query->groupBy($params['groupBy']);
        }
        if (isset($params['pageSize']) && $params['pageSize']) {
            static::setPaging($query, $params['pageSize']);
        }
        if (isset($params['limit'])) {
            return $query->limit($params['limit'])->offset(0)->asArray()->all();
        }
        if (isset($params['sum'])) {
            if (is_array($params['sum'])) {
                $select = array_map(function ($item) {
                    return "SUM({$item}) as {$item}";
                }, $params['sum']);
                return $query->select($select)->asArray()->one();
            } else {
                return $query->sum($params['sum']) ?: '0';
            }
        }
        if (isset($params['count'])) {
            return $query->count();
        }
        if (isset($params['exists'])) {
            return $query->exists();
        }
        return $query->asArray()->all();
    }


    /**
     * Notes:获取列表查询SQL
     * Date: 2020/6/17
     * Time: 11:29
     * @param array $params
     * @return string
     */
    public static function getSelectSql($params = [])
    {
        $query = static::find();
        if (isset($params['select'])) {
            $query->select($params['select']);
        } else {
            $query->select(static::getPk());
        }
        if (isset($params['where'])) {
            $query->where($params['where']);
        }
        if (isset($params['orderBy'])) {
            $query->orderBy($params['orderBy']);
        }
        if (isset($params['groupBy'])) {
            $query->groupBy($params['groupBy']);
        }
        if (isset($params['pageSize']) && $params['pageSize']) {
            static::setPaging($query, $params['pageSize']);
        }
        if (isset($params['limit'])) {
            $query->limit($params['limit']);
        }
        $commandQuery = clone $query;
        $sql = $commandQuery->createCommand()->getRawSql();
        return $sql;
    }


    /**
     * Notes:通过主键实例对象
     * Date: 2020/7/20
     * Time: 14:17
     * @param $id
     * @return static|null
     */
    public static function findOneById($id)
    {
        $oneModel = new static();
        if (!$data = $oneModel->findDataById($id)) {
            return null;
        }
        $attributes = $oneModel->attributes();
        foreach ($attributes as $name) {
            if (isset($data[$name])) {
                $oneModel->$name = $data[$name];
                $oneModel->setAttribute($name, $data[$name]);
                $oneModel->setOldAttribute($name, $data[$name]);
            }
        }
        return $oneModel;
    }

    /**
     * Notes:以数组形式从数据库获取单条数据
     * Date: 2020/6/17
     * Time: 11:41
     * @param $id
     * @return array|\yii\db\ActiveRecord|null
     */
    public static function findDataById($id)
    {
        return static::find()->where([static::getPk() => $id])->asArray()->one();
    }


    /**
     * Notes:通过主键批量获取数据
     * Date: 2020/6/17
     * Time: 11:42
     * @param $ids
     * @return array
     */
    public static function findDatumByIds($ids)
    {
        $datum = [];
        foreach ($ids as $id) {
            $datum[] = static::findDataById($id);
        }
        return $datum;
    }

    /**
     * Notes:保存此对象的属性数据
     * Date: 2020/7/24
     * Time: 15:26
     * @param $rows
     * @return int
     * @throws Exception
     */
    public static function batchAddData($rows)
    {
        return Yii::$app->getDb()->createCommand()
            ->batchInsert(static::tableName(), static::columns(), $rows)->execute();
    }


    /**
     * Notes:通过主键修改数据
     * Date: 2020/6/17
     * Time: 11:43
     * @param $params
     * @param $id
     * @return int
     */
    public static function updateDataById($params, $id)
    {
        return static::updateAll($params, [static::getPk() => $id]);
    }

    /**
     * Notes:获取主键修改数据的SQL
     * Date: 2020/6/17
     * Time: 11:43
     * @param $params
     * @param $id
     * @return int
     */
    public static function updateDataByIdSql($params, $id)
    {
        $command = static::getDb()->createCommand();
        $command->update(static::tableName(), $params, [static::getPk() => $id]);
        return $command->getRawSql();
    }

    /**
     * Notes:直接运行SQL语句
     * Date: 2020/6/17
     * Time: 11:44
     * @param $sql
     * @return Command
     */
    public static function executeSql($sql)
    {
        return Yii::$app->db->createCommand($sql);
    }

    /**
     * Notes:设置分页
     * Date: 2020/6/17
     * Time: 11:39
     * @param $query
     * @param $pageSize
     */
    public static function setPaging($query, $pageSize)
    {
        $count = $query->count();
        $page = new Pagination([
            'totalCount' => $count,
            'pageSize' => $pageSize,
            'pageSizeParam' => false,
            'route' => false,
            'validatePage' => false
        ]);
        static::setCount($count);
        static::setPage($page->getPageCount());
        static::setPageSize($page->getPageSize());
        $query->limit($page->limit)->offset($page->offset);
    }

    /**
     * Notes:获取页码
     * Date: 2020/6/17
     * Time: 11:30
     * @return int
     */
    public static function getPage()
    {
        return static::$page;
    }

    /**
     * Notes:设置页码
     * Date: 2020/6/17
     * Time: 11:30
     * @param int $page
     */
    public static function setPage(int $page)
    {
        static::$page = (int)$page;
    }

    /**
     * Notes:获取页条数
     * Date: 2020/6/17
     * Time: 11:31
     * @return int
     */
    public static function getPageSize()
    {
        return static::$pageSize;
    }

    /**
     * Notes:设置页条数
     * Date: 2020/6/17
     * Time: 11:31
     * @param int $pageSize
     */
    public static function setPageSize(int $pageSize)
    {
        static::$pageSize = (int)$pageSize;
    }

    /**
     * Notes:获取条数
     * Date: 2020/6/17
     * Time: 11:30
     * @return int
     */
    public static function getCount()
    {
        return static::$count;
    }

    /**
     * Notes:设置条数
     * Date: 2020/6/17
     * Time: 11:30
     * @param int $count
     */
    public static function setCount(int $count)
    {
        static::$count = (int)$count;
    }


}